package com.lingyun.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.lingyun.common.exception.ServiceException;
import com.lingyun.common.mapper.LyMenuMapper;
import com.lingyun.common.mapper.LyRoleMapper;
import com.lingyun.common.pojo.LyMenu;
import com.lingyun.common.utils.security.SecurityUtils;
import com.lingyun.common.vo.LoginUser;
import com.lingyun.common.vo.menu.Router;
import com.lingyun.common.vo.menu.Meta;
import com.lingyun.system.service.LyMenuService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * (LyLeftNav)表服务实现类
 *
 * @author 没事别学JAVA
 * @since 2021-11-10 16:19:26
 */
@Service("lyNavService")
public class LyMenuServiceImpl extends ServiceImpl<LyMenuMapper, LyMenu> implements LyMenuService {

    @Resource
    LyMenuMapper lyMenuMapper;

    @Resource
    LyRoleMapper lyRoleMapper;

    /**
     * 查询登录角色拥有的菜单
     * @return  菜单集合
     */
    @Override
    public List<LyMenu> menuList() {
        LoginUser  loginUser= null;
        try {
            loginUser= SecurityUtils.getLoginUser();
        } catch (ServiceException e) {
            e.printStackTrace();
        }
        if(loginUser.getRoles().contains("admin")){
            return getChildPerms(lyMenuMapper.menuList(), 0);
        }else{
            List<LyMenu> listnav= lyMenuMapper.queryMentuByRoleId(loginUser.getUserId());
            return getChildPerms(listnav.stream().distinct().collect(Collectors.toList()), 0);
        }
    }

    /**
     * 获取树状图信息
     * @return  树状图信息
     */
    @Override
    public List<LyMenu> roleMenuTress() {
        LoginUser  loginUser= null;
        try {
            loginUser= SecurityUtils.getLoginUser();
        } catch (ServiceException e) {
            e.printStackTrace();
        }
        if(loginUser.getRoles().contains("admin")){
            return getChildPerms(lyMenuMapper.roleMenuTress(), 0);
        }else{
            List<LyMenu> listnav= lyMenuMapper.roleNavTressById(loginUser.getUserId());
            return getChildPerms(listnav.stream().distinct().collect(Collectors.toList()), 0);
        }
    }

    /**
     * 构建前端路由所需要的左侧导航栏菜单
     */
    @Override
    public List<Router> buildMenu(List<LyMenu> menus) {

        List<Router> routerList = new LinkedList<Router>();
        for (LyMenu nav : menus) {
            Router router = new Router();

            router.setNavName(nav.getMenuName());
            router.setPath(nav.getPath());
            router.setHidden("1".equals(nav.getVisible()));
            router.setTarget(nav.getTarget());

            Meta metaVo = new Meta();
            metaVo.setIcon(nav.getIcon());
            metaVo.setTitle(nav.getMenuName());
            router.setMeta(metaVo);

            List<LyMenu> zMenu = nav.getChildren();
            if (!zMenu.isEmpty() && zMenu.size() > 0 && nav.getMenuType().equals("A")) {   // 子类不为空  大于0  是目录的
                router.setChild(true);
                router.setChildren(buildMenu(zMenu));
            }else if(!zMenu.isEmpty() && zMenu.size() > 0 && nav.getMenuType().equals("B")){  // 子类不为空  大于0  是菜单的
                Boolean isHidden =false;
                for (LyMenu menu : zMenu) {
                    if(menu.getVisible().equals("1")){
                        isHidden = true;
                        break;
                    }
                }
                if(isHidden){
                    router.setChild(true);
                    router.setChildren(buildMenu(zMenu));
                }else{
                    router.setChild(false);
                }
            } else if(nav.getMenuType().equals("B") && zMenu.isEmpty()){  // 是菜单的 子类为空
                router.setChild(false);
            }else {                                        // 其他
                router.setChild(false);
            }
            routerList.add(router);


        }
        return routerList;
    }

    /**
     * 更具用户ID获取权限
     * @param userId 用户id
     * @return 当前用户 校色的权限
     */
    @Override
    public Set<String> selectUserPermsByUserId(Long userId) {
        List<String> perms = lyMenuMapper.selectUserPermsByUserId(userId);
        Set<String> permsSet = new HashSet<>();
        for (String perm : perms) {
            if (StrUtil.isNotEmpty(perm)) {
                permsSet.addAll(Arrays.asList(perm.trim().split(",")));  //

            }
        }
        return permsSet;
    }

    /**
     * 为 admin 角色获取全部权限
     * @return 返回全部权限
     */
    @Override
    public Set<String> selectAdminUserPermsAll() {
        List<String> perms = lyMenuMapper.selectAdminUserPermsAll();
        Set<String> permsSet = new HashSet<>();
        for (String perm : perms) {
            if (StrUtil.isNotEmpty(perm)) {
                permsSet.addAll(Arrays.asList(perm.trim().split(",")));  //
            }
        }
        return permsSet;
    }


    /**
     * 根据角色id 获取角色所拥有的导航 id 列表
     * @param roleId
     * @return
     */
    @Override
    public List<Long> selectMenuByRoleId(Long roleId) {
        if(lyRoleMapper.selectRoleById(roleId).getRoleKey().equals("admin")){
            return lyMenuMapper.getMenuIdAll();
        }
        return lyMenuMapper.selectMenuByRoleId(roleId);
    }


    /**
     * 根据父id获取 子菜单 和 子按钮
     *
     * @param parentId  父id
     * @return 集合
     */
    @Override
    public List<Long> selectParentId(Long parentId) {

        return lyMenuMapper.selectParentId(parentId);

    }


    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list     分类表
     * @param parentId 传入的父节点ID
     * @return String
     */
    public List<LyMenu> getChildPerms(List<LyMenu> list, int parentId) {

        List<LyMenu> returnList = new ArrayList<LyMenu>();

        for (Iterator<LyMenu> iterator = list.iterator(); iterator.hasNext(); ) {
            LyMenu t = (LyMenu) iterator.next();
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() == parentId) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<LyMenu> list, LyMenu t) {
        // 得到子节点列表
        List<LyMenu> childList = getChildList(list, t);
        t.setChildren(childList);
        for (LyMenu tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<LyMenu> getChildList(List<LyMenu> list, LyMenu t) {
        List<LyMenu> tlist = new ArrayList<LyMenu>();
        Iterator<LyMenu> it = list.iterator();
        while (it.hasNext()) {
            LyMenu n = (LyMenu) it.next();
            if (n.getParentId().longValue() == t.getMenuId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<LyMenu> list, LyMenu t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }


}
